package com.ccteam.admin.view.fragments.music

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.os.bundleOf
import androidx.core.widget.addTextChangedListener
import androidx.core.widget.doOnTextChanged
import androidx.fragment.app.Fragment
import androidx.fragment.app.setFragmentResult
import androidx.fragment.app.setFragmentResultListener
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import cn.hutool.core.date.DateUtil
import com.ccteam.admin.R
import com.ccteam.admin.REFRESH_REQUEST_KEY
import com.ccteam.admin.databinding.FragmentMusicAddBinding
import com.ccteam.admin.utils.EventObserver
import com.ccteam.admin.utils.LoadMessage
import com.ccteam.admin.view.adapters.SelectArtistAdapter
import com.ccteam.admin.view.adapters.SelectArtistItemClickCallback
import com.ccteam.admin.view.bean.SelectInfoResult
import com.ccteam.admin.view.fragments.common.SelectFragment
import com.ccteam.admin.viewmodels.music.MusicAddViewModel
import com.ccteam.admin.viewmodels.music.MusicEditInfo
import com.google.android.material.snackbar.Snackbar
import com.orhanobut.logger.Logger
import dagger.hilt.android.AndroidEntryPoint

/**
 * @author Xiaoc
 * @since 2021/4/20
 */
@AndroidEntryPoint
class MusicAddFragment: Fragment() {

    private var _binding: FragmentMusicAddBinding? = null
    private val binding get() = _binding!!

    private val musicAddViewModel by viewModels<MusicAddViewModel>()

    private val args by navArgs<MusicAddFragmentArgs>()

    /**
     * 选择图片的内容
     * 选择完手机中的图片后，将其存储到ViewModel中并进行对应UI更新
     */
    private val selectImage = registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
        uri?.let {
            musicAddViewModel.parseMusicInfo(it)
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setFragmentResultListener(SelectFragment.SELECT_REQUEST_KEY){ _, bundle ->
            val albumArtistInfo = bundle.getParcelable<SelectInfoResult>(
                SelectFragment.SELECT_RESULT
            )

            albumArtistInfo?.let {
                musicAddViewModel.addSelectArtist(it)
            }
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentMusicAddBinding.inflate(inflater,container,false)
        binding.tvCurrentAlbum.text = getString(R.string.description_music_edit_album_info,args.albumName)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

        val adapter = SelectArtistAdapter(callback)
        binding.rvSelectArtist.adapter = adapter

        musicAddViewModel.enableAddButton.observe(viewLifecycleOwner, {
            binding.btnAdd.isEnabled = it
        })

        musicAddViewModel.addLoadMessage.observe(viewLifecycleOwner,EventObserver{
            binding.btnAdd.setLoading(it is LoadMessage.Loading)
            if(it is LoadMessage.Success){
                Snackbar.make(
                    binding.root,
                    getString(R.string.description_success),
                    Snackbar.LENGTH_SHORT
                ).setAnchorView(binding.btnAdd).show()
                setFragmentResult(REFRESH_REQUEST_KEY, bundleOf(REFRESH_REQUEST_KEY to true))
                findNavController().navigateUp()
            } else if(it is LoadMessage.Error){
                Snackbar.make(
                    binding.root,
                    it.errorMessage.description.toString(),
                    Snackbar.LENGTH_SHORT
                ).setAnchorView(binding.btnAdd).show()
            }
        })

        musicAddViewModel.editMusicInfo.observe(viewLifecycleOwner, {
            updateMusicInfo(it)
        })

        musicAddViewModel.selectArtistList.observe(viewLifecycleOwner, {
            adapter.submitList(it)
            adapter.notifyDataSetChanged()
        })

        binding.btnSelectArtists.setOnClickListener {
            findNavController().navigate(MusicAddFragmentDirections.actionMusicAddFragmentToSelectFragment(
                SelectFragment.SELECT_ARTIST
            ))
        }

        binding.editMusicName.addOnEditTextAttachedListener { inputLayout ->
            inputLayout.editText?.doOnTextChanged { text, _, _, _ ->
                musicAddViewModel.setMusicName(text.toString())
                val musicNameSuccess = if(text.toString().isNotEmpty() && text.toString().length in 1..100){
                    inputLayout.error = null
                    true
                } else {
                    inputLayout.error = getString(R.string.description_music_edit_error_musicName)
                    false
                }
                musicAddViewModel.setMusicNameSuccess(musicNameSuccess)
            }
        }

        binding.editMusicDuration.addOnEditTextAttachedListener { inputLayout ->
            inputLayout.editText?.doOnTextChanged { text, _, _, _ ->
                musicAddViewModel.setDuration(text.toString())
                val durationSuccess = if(text.toString().isNotEmpty()){
                    inputLayout.error = null
                    true
                } else {
                    inputLayout.error = getString(R.string.description_music_edit_error_duration)
                    false
                }
                musicAddViewModel.setDurationSuccess(durationSuccess)
            }
        }

        binding.editMusicYear.addOnEditTextAttachedListener { inputLayout ->
            inputLayout.editText?.doOnTextChanged { text, _, _, _ ->
                musicAddViewModel.setSongYear(text.toString())

                val songYearSuccess = try {
                    val date = DateUtil.format(DateUtil.parse(text),"yyyy-MM-dd")
                    if(date.isNullOrEmpty()){
                        throw NullPointerException()
                    }
                    musicAddViewModel.setSongYear(date)
                    inputLayout.error = null
                    true
                } catch (e: Exception){
                    inputLayout.error = getString(R.string.description_music_edit_error_musicYear)
                    false
                }
                musicAddViewModel.setSongYearSuccess(songYearSuccess)
            }
        }

        binding.editMusicTrack.addOnEditTextAttachedListener { inputLayout ->
            inputLayout.editText?.doOnTextChanged { text, _, _, _ ->
                musicAddViewModel.setTrack(text.toString())
                val trackSuccess = if(text.toString().isNotEmpty()){
                    inputLayout.error = null
                    true
                } else {
                    inputLayout.error = getString(R.string.description_music_edit_error_track)
                    false
                }
                musicAddViewModel.setTrackSuccess(trackSuccess)
            }
        }

        binding.editLrc.addOnEditTextAttachedListener { inputLayout ->
            inputLayout.editText?.doOnTextChanged { text, _, _, _ ->
                musicAddViewModel.setLrc(text.toString())
            }
        }

        binding.btnAdd.setProgressButtonOnClickListener{
            musicAddViewModel.addMusic()
        }

        binding.btnSelectMusicFile.setOnClickListener {
            selectImage.launch("audio/*")
        }
    }

    private val callback = object: SelectArtistItemClickCallback {
        override fun deleteClick(item: SelectInfoResult) {
            musicAddViewModel.removeSelectArtist(item)
        }
    }

    private fun updateMusicInfo(musicInfo: MusicEditInfo) = with(binding){
        editMusicId.editText?.setText(musicInfo.id)
        editMusicName.editText?.setText(musicInfo.name)
        editMusicDuration.editText?.setText(musicInfo.duration)
        editMusicTrack.editText?.setText(musicInfo.track)
        editMusicYear.editText?.setText(musicInfo.songYear)
        editLrc.editText?.setText(musicInfo.lrc)
    }

    override fun onDestroyView() {
        super.onDestroyView()
        binding.editMusicName.clearOnEditTextAttachedListeners()
        binding.editMusicDuration.clearOnEditTextAttachedListeners()
        binding.editMusicYear.clearOnEditTextAttachedListeners()
        binding.editMusicTrack.clearOnEditTextAttachedListeners()
        binding.editLrc.clearOnEditTextAttachedListeners()

        _binding = null
    }
}